package nig.test;

import ch.ethz.ssh2.Session;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter;

/**
 *
 * @author King Lung chiu
 */
public class KeyGen {
   public static void main(String args[]) throws NoSuchAlgorithmException, IOException, JSchException {
      KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
      kpg.initialize(2048);
      KeyPair kp = kpg.genKeyPair();
      PublicKey pub = kp.getPublic();
      PrivateKey prv = kp.getPrivate();
      
      keyWrite_Raw(pub, "keygen_rsa_raw.pub");
      keyWrite_Raw(prv, "keygen_rsa_raw.prv");
      
      
      StringBuilder msg = new StringBuilder()
         .append("\nPublic Key =================================================")
         .append("\n toString: ")
         .append(pub.toString())
         .append("\nalgorithm: ")
         .append(pub.getAlgorithm())
         .append("\n   format: ")
         .append(pub.getFormat())
         .append("\n  encoded: ")
         .append(base64Encode(pub.getEncoded()))
         .append("\nPrivate Key ================================================")
         .append("\n toString: ")
         .append(prv.toString())
         .append("\nalgorithm: ")
         .append(prv.getAlgorithm())
         .append("\n   format: ")
         .append(prv.getFormat())
         .append("\n  encoded: ")
         .append(base64Encode(prv.getEncoded()))
      ;
     

      RSAPrivateKey rsaPrvKey = (RSAPrivateKey) prv;
      byte[] privateE = rsaPrvKey.getPrivateExponent().toByteArray();
      byte[] modulus = rsaPrvKey.getModulus().toByteArray();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      encodeUInt32(privateE.length, baos);
      baos.write(privateE);
      encodeUInt32(modulus.length, baos);
      baos.write(modulus);
      
      StringWriter sw = new StringWriter();
      PemWriter pw = new PemWriter(sw);
//      pw.writeObject(new PemObject("RSA PRIVATE KEY", prv.getEncoded()));
      pw.writeObject(new PemObject("RSA PRIVATE KEY", baos.toByteArray()));
      pw.close();
      msg
         .append("\n\nPrivate Key PEM=============================================\n")
         .append(sw.toString())
      ;
      System.out.println(msg.toString());
      
      
      FileWriter pkcs8Prv = new FileWriter("keygen_rsa.pkcs8");
      pkcs8Prv.write(base64Encode(prv.getEncoded()));
      pkcs8Prv.close();
      
      FileWriter fwPrv = new FileWriter("keygen_rsa");
      fwPrv.write(sw.toString());
      fwPrv.close();
      
      FileWriter fwPub = new FileWriter("keygen_rsa.pub");
      fwPub.write("ssh-rsa ");
      fwPub.write(base64Encode(pub.getEncoded()));
      fwPub.write(" user@daris\n");
      fwPub.close();
      
      
      
//      BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
//      System.out.print("enter key file: ");
//      final String filename = stdin.readLine();
//      PemReader pemFile = new PemReader(new FileReader(filename));
      PemReader pemFile = new PemReader(new FileReader("keygen_rsa"));
      PemObject pem = pemFile.readPemObject();
      pemFile.close();
      StringBuilder pemMsg = new StringBuilder()
         .append("\n\nPEM File Content =================================================")
         .append("\n     type: ")
         .append(pem.getType())
         .append("\n  content: ")
         .append(base64Encode(pem.getContent()))
      ;
      System.out.println(pemMsg.toString());
      
      PemObject privKey = new PemObject("RSA PRIVATE KEY", pem.getContent());

   
      // =========================
      
      
   
   }
   
   public static void pushKeyPair(Session ssh) throws JSchException, FileNotFoundException, IOException {
      com.jcraft.jsch.KeyPair kpair = com.jcraft.jsch.KeyPair.genKeyPair(
         new JSch(), com.jcraft.jsch.KeyPair.RSA, 2048);
      kpair.writePrivateKey("keygen_jsch_rsa.prv");
      kpair.writePublicKey("keygen_jsch_rsa.pub", "userXYZ@daris1");
      System.out.println("Finger print: "+kpair.getFingerPrint());
      kpair.dispose();
      
   }
   
   public static void keyWrite_Raw(Key k, String fileName) throws FileNotFoundException, IOException {
      byte[] keybytes = k.getEncoded();
      FileOutputStream fos = new FileOutputStream(fileName);
      fos.write(keybytes);
      fos.close();
   }

   public static String base64Encode(byte[] rawBytes) {
      return DatatypeConverter.printBase64Binary(rawBytes);
   }

   public static void encodeUInt32(int value, OutputStream out) throws IOException
   {
       byte[] tmp = new byte[4];
       tmp[0] = (byte)((value >>> 24) & 0xff);
       tmp[1] = (byte)((value >>> 16) & 0xff);
       tmp[2] = (byte)((value >>> 8) & 0xff);
       tmp[3] = (byte)(value & 0xff);
       out.write(tmp);
   }
}
